home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
- Program simult.c by Stan Misel 11/6/84
- ***********************************************************************/
- #include <stdio.h>
- #define MAXEQ 20 /* Max size of arrays to store coefficients */
- #define ABS(x) ((x>0)?x:-x) /* Macro routine returns absolute value for any
- * data type. Used to avoid having to load the
- * floating point abs value function fabs()from
- * the UNIX math library
- */
- double atof(); /* Library function */
- void parse(); /* Local function */
- void gauss(); /* Local function */
- void backtrak(); /* Local function */
- main()
- {
- char buf[BUFSIZ];
- int n;
- int k;
- int row, col;
- int index;
- double coef[MAXEQ][MAXEQ];
- printf("\n\n\nHow many equations? ");
- gets(buf);
- n = atoi(buf);
- if(n <= 0) {
- printf("Not a valid number\n");
- exit(-1);
- }
- printf("Enter the coefficients of the equations separated byspaces\n");
- printf("Note: The 1st coefficient of the 1st equation cannot be0!\n");
- for (k=1; k<=n; ++k) {
- printf("Equation # %d ==> ",k);
- row = k - 1;
- gets(buf);
- parse(buf,coef[row], n);
- }
- for(index = 0;index < n-1;++index) {
- pivot(coef, n, index);
- gauss(coef,n,index);
- }
- backtrak(coef, n);
- printf("\n\nSolutions:\n");
- for(row=0;row < n;row++)
- printf( "X%d = %f\n",row+1,coef[row][n]);
- }
- void parse(str, list, nel)
- char *str;
- double *list;
- int nel;
- /* Function stuffs blank separated numeric ASCII values into a row of
- * a 2 dimensional array. The values may be integers or real.
- * Numbers entered may have a leading minus sign, but no plus
- * sign. Do not input any extraneous spaces or parser will
- * complain and end program. It will also quit if the number
- * of equations or unknowns is inconsistent.
- */
- {
- char tmp[20];
- char *ptmp;
- char c;
- int i = 0;
- while(1) {
- ptmp = tmp;
- while ((c = *str++) != ' ' && c != '\0'){
- *ptmp++ = c;
- }
- *ptmp = '\0';
- *(list+i) = atof(tmp);
- ++i;
- if (i > nel+1){
- printf("too many elements\n");
- exit(-1);
- }
- if(c == '\0')
- break;
- }
- if(i != nel+1) {
- printf("Not enough elements\n");
- exit(-1);
- }
- }
- pivot(arrayp,nel,index)
- double arrayp[][MAXEQ];
- int nel;
- int index;
-
- /* Function implements the PIVOT routine described by Dence to
- * select rows for gaussian elimination that would suffer least
- * from inevitable computer roundoff errors.
- */
-
- {
- int row, col;
- int pivrow;
- double max[MAXEQ];
- double x;
- for(row=0; row <= nel; ++row) /* Initialize max array to zeros */
- max[row] = 0.0;
- for (row=index; row < nel; ++row) {
- for(col=index; col < nel; ++col) {
- max[row] = ((x=ABS(arrayp[row][col])) > max[row]) ? x :
- max[row];
- }
- }
- /* The array max[] contains the values of the largest elements in
- * each of the rows of the array, exclusive of the rightmost element.
- * Now we will find the pivot row.
- */
- pivrow = index;
- for(row=index; row <nel; ++row) {
- max[row] = ABS(arrayp[row][index]) / max[row];
- pivrow = (max[row] >max[pivrow]) ? row : pivrow;
- }
- /* We are finished with the array max, so we can use it as a swap
- * area to move our pivot array to the first row.
- */
- for(col = index; col <= nel; ++col) {
- max[col] = arrayp[index][col];
- arrayp[index][col] = arrayp[pivrow][col];
- arrayp[pivrow][col] = max[col];
- }
- } /* End of function */
-
- void gauss(arr, nel,index)
- double arr[][MAXEQ];
- int nel;
- int index;
-
- /* Function to multiply and add rows in the matrix to reduce
- * to one equation for one unknown.
- */
-
- {
- int row, col, i;
- double factor;
-
- for(row = 1+index; row < nel;++row) {
- factor = -(arr[row][index] / arr[index][index]);
- for(i=index; i <= nel; ++i) {
- arr[row][i] += factor * arr[index][i];
- }
- }
- }
-
- void backtrak(array, nel)
- double array[][MAXEQ];
- int nel;
-
- /* Function solves for all variables after the array was reduced by
- * the gaussian elimination function.
- */
-
- {
- int step,col,row;
-
- --nel;
- array[nel][nel+1] /= array[nel][nel];
- array[nel][nel]=1;
- for(step = 1; step <= nel; ++step) {
- row=nel-step;
- for(col=row+1;col<= nel;++col) {
- array[row][nel+1] = -array[row][col]*array[col][nel+1]
- +array[row][nel+1];
- array[row][col]=0;
- }
- array[row][nel+1]=array[row][nel+1]/array[row][row];
- array[row][row]=1;
- }
- }
-